﻿using Dapper;
using Estsh.Core.Base;
using Estsh.Core.Dapper;
using Estsh.Core.Wms.IRepositories;
using Estsh.Core.Model.Result;
using Estsh.Core.Repositories;
using System.Collections;
using System.Data;
using System.Text;
using System.Security.Cryptography;
using System.Text.Json;
using Estsh.Core.Models;
using Newtonsoft.Json.Linq;
using Estsh.Core.Model.EnumUtil;
using Estsh.Core.Util;
using Estsh.Core.Model.Extend.Models;

namespace Estsh.Core.Wms.Repositories
{
    public class NcScrapRepository : BaseRepository<BaseEntity>, INcScrapRepository
    {
        public NcScrapRepository(DapperDbContext _dapperDbContext) : base(_dapperDbContext)
        {

        }

        /// <summary>
        /// 处理报废
        /// </summary>
        /// <param name="cartonInfo"></param>
        /// <param name="moveDetail"></param>
        /// <param name="moveSn"></param>
        /// <returns></returns>
        public bool DoScrap(SysStock cartonInfo, WmsMoveDetail moveDetail, WmsMoveSn? moveSn, string loginId)
        {
            List<string> sqlStrings = new List<string>();
            List<DynamicParameters> parameterList = new List<DynamicParameters>();

            //更改条码表状态,已报废
            StringBuilder updateSql = new StringBuilder(1024);
            updateSql.Append("UPDATE sys_stock ");
            updateSql.Append("SET status = @status, ");
            updateSql.Append("    locate_id = @locateId, ");
            updateSql.Append("    locate_name = @locateName, ");
            updateSql.Append("    zone_id = @zoneId, ");
            updateSql.Append("    zone_name = @zoneName, ");
            updateSql.Append("    warehouse_id = @warehouseId, ");
            updateSql.Append("    warehouse_name = @warehouseName, ");
            updateSql.Append("    erp_warehouse = @erpWarehouse, ");
            updateSql.Append("    update_userid = @updateUserid, ");
            updateSql.Append("    update_time = @updateTime ");
            updateSql.Append("WHERE carton_no = @cartonNo ");
            DynamicParameters updateParameters = new DynamicParameters();
            updateParameters.Add("@cartonNo", cartonInfo.CartonNo);
            updateParameters.Add("@status", WmsEnumUtil.StockStatus.SCRAPED);
            updateParameters.Add("@locateId", 0);
            updateParameters.Add("@locateName", null);
            updateParameters.Add("@zoneId", 0);
            updateParameters.Add("@zoneName", null);
            updateParameters.Add("@warehouseId", 0);
            updateParameters.Add("@warehouseName", null);
            updateParameters.Add("@erpWarehouse", null);
            updateParameters.Add("@updateUserid", loginId);
            updateParameters.Add("@updateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));

            sqlStrings.Add(updateSql.ToString());
            parameterList.Add(updateParameters);

            //更新单据主表-处理中
            updateSql.Remove(0, updateSql.Length);
            updateSql.Append("UPDATE dbo.wms_move_header ");
            updateSql.Append("SET order_status = @orderStatus, ");
            updateSql.Append("    update_userid = @updateUserid, ");
            updateSql.Append("    update_time = @updateTime ");
            updateSql.Append("WHERE order_no = @orderNo ");
            updateSql.Append("      AND order_status < @orderStatus2 ");

            updateParameters = new DynamicParameters();
            updateParameters.Add("@orderStatus", WmsEnumUtil.MoveOrderStatus.PROCESSING);
            updateParameters.Add("@updateUserid", loginId);
            updateParameters.Add("@updateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            updateParameters.Add("@orderNo", moveDetail.OrderNo);
            updateParameters.Add("@orderStatus2", WmsEnumUtil.MoveOrderStatus.PROCESSING);

            sqlStrings.Add(updateSql.ToString());
            parameterList.Add(updateParameters);


            bool isDetailComplate = cartonInfo.Qty + moveDetail.PickQty >= moveDetail.Qty;

            //更新单据明细表--处理中或完成
            updateSql.Remove(0, updateSql.Length);
            updateSql.Append("UPDATE dbo.wms_move_detail ");
            updateSql.Append("SET pick_qty = pick_qty + @qty, ");
            updateSql.Append("    item_status = @itemStatus, ");
            updateSql.Append("    update_userid = @updateUserid, ");
            updateSql.Append("    update_time = @updateTime ");
            updateSql.Append("WHERE order_no = @orderNo ");
            updateSql.Append("      AND part_id = @partId ");

            updateParameters = new DynamicParameters();
            updateParameters.Add("@orderNo", moveDetail.OrderNo);
            updateParameters.Add("@partId", moveDetail.PartId);
            updateParameters.Add("@qty", cartonInfo.Qty);
            if (isDetailComplate)
            {
                updateParameters.Add("@itemStatus", WmsEnumUtil.MoveOrderDetailStatus.COMPLETED);
            }
            else
            {
                updateParameters.Add("@itemStatus", WmsEnumUtil.MoveOrderDetailStatus.BATCHING);
            }

            updateParameters.Add("@updateUserid", loginId);
            updateParameters.Add("@updateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));


            sqlStrings.Add(updateSql.ToString());
            parameterList.Add(updateParameters);


            if (moveSn == null)
            {
                //插入单据条码表
                updateSql.Remove(0, updateSql.Length);
                updateSql.Append("INSERT INTO dbo.wms_move_sn ");
                updateSql.Append("( ");
                updateSql.Append("    order_no,item_no,part_id,part_no,part_spec, ");
                updateSql.Append("    carton_no,qty,unit,status,factory_id,factory_code,enabled, ");
                updateSql.Append("    create_userid,create_time,update_userid,update_time,guid ");
                updateSql.Append(") ");
                updateSql.Append("VALUES ");
                updateSql.Append("(   @orderNo,@itemNo,@partId,@partNo,@partSpec, ");
                updateSql.Append("    @cartonNo,@qty,@unit,@status,@factoryId,@factoryCode,@enabled, ");
                updateSql.Append("    @createUserid,@createTime,@updateUserid,@updateTime,@guid ");
                updateSql.Append("    ) ");

                updateParameters = new DynamicParameters();
                updateParameters.Add("@orderNo", moveDetail.OrderNo);
                updateParameters.Add("@itemNo", moveDetail.ItemNo);
                updateParameters.Add("@partId", moveDetail.PartId);
                updateParameters.Add("@partNo", moveDetail.PartNo);
                updateParameters.Add("@partSpec", moveDetail.PartSpec);
                updateParameters.Add("@cartonNo", cartonInfo.CartonNo);
                updateParameters.Add("@qty", cartonInfo.Qty);
                updateParameters.Add("@unit", cartonInfo.Unit);
                updateParameters.Add("@status", (int)WmsEnumUtil.MoveOrderSnStatus.PROCESSED);
                updateParameters.Add("@factoryId", moveDetail.FactoryId);
                updateParameters.Add("@factoryCode", moveDetail.FactoryCode);
                updateParameters.Add("@enabled", WmsEnumUtil.Enabled.Y.ToString());
                updateParameters.Add("@createUserid", loginId);
                updateParameters.Add("@createTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                updateParameters.Add("@updateUserid", loginId);
                updateParameters.Add("@updateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                updateParameters.Add("@guid", Guid.NewGuid());

                sqlStrings.Add(updateSql.ToString());
                parameterList.Add(updateParameters);
            }
            else
            {
                //更新单据条码表
                updateSql.Remove(0, updateSql.Length);
                updateSql.Append("UPDATE dbo.wms_move_sn ");
                updateSql.Append("SET status = @status, ");
                updateSql.Append("    update_userid = @updateUserid, ");
                updateSql.Append("    update_time = @updateTime ");
                updateSql.Append("WHERE order_no = @orderNo ");
                updateSql.Append("      AND carton_no = @cartonNo ");

                updateParameters = new DynamicParameters();
                updateParameters.Add("@orderNo", moveDetail.OrderNo);
                updateParameters.Add("@cartonNo", cartonInfo.CartonNo);
                updateParameters.Add("@status", (int)WmsEnumUtil.MoveOrderSnStatus.PROCESSED);
                updateParameters.Add("@updateUserid", loginId);
                updateParameters.Add("@updateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));

                sqlStrings.Add(updateSql.ToString());
                parameterList.Add(updateParameters);
            }

            //新增 sys_stock_trans 事务表
            updateSql.Remove(0, updateSql.Length);
            updateSql.Append("INSERT INTO [dbo].[sys_stock_trans] ");
            updateSql.Append("( ");
            updateSql.Append("    [trans_code],[carton_no],[part_id],[part_no],[part_spec],[src_locate_id],[src_locate_name],[dest_locate_id], ");
            updateSql.Append("    [dest_locate_name],[old_qty],[new_qty],[trans_qty],[old_status],[new_status],[old_qms_status],[new_qms_status],[unit], ");
            updateSql.Append("    [factory_id],[factory_code],[src_erp_warehouse],[dest_erp_warehouse],[src_warehouse_id],[src_warehouse_name], ");
            updateSql.Append("    [dest_warehouse_id],[dest_warehouse_name],[src_zone_id],[src_zone_name],[dest_zone_id],[dest_zone_name],[enabled], ");
            updateSql.Append("    [update_userid],[update_time], [create_userid],[create_time],[guid] ");
            updateSql.Append(") ");
            updateSql.Append("VALUES ");
            updateSql.Append("(@trans_code, @carton_no, @part_id, @part_no, @part_spec, @src_locate_id, @src_locate_name, @dest_locate_id, ");
            updateSql.Append(" @dest_locate_name, @old_qty, @new_qty, @trans_qty, @old_status, @new_status, @old_qms_status, @new_qms_status, @unit, ");
            updateSql.Append(" @factory_id, @factory_code, @src_erp_warehouse, @dest_erp_warehouse, @src_warehouse_id, @src_warehouse_name, ");
            updateSql.Append(" @dest_warehouse_id, @dest_warehouse_name, @src_zone_id, @src_zone_name, @dest_zone_id, @dest_zone_name, @enabled, ");
            updateSql.Append(" @update_userid, @update_time, @create_userid, @create_time, @guid) ");


            updateParameters = new DynamicParameters();
            updateParameters.Add("@trans_code", (int)WmsEnumUtil.TransType.NC_SCRAP);
            updateParameters.Add("@carton_no", cartonInfo.CartonNo);
            updateParameters.Add("@part_id", cartonInfo.PartId);
            updateParameters.Add("@part_no", cartonInfo.PartNo);
            updateParameters.Add("@part_spec", cartonInfo.PartSpec);
            updateParameters.Add("@src_locate_id", cartonInfo.LocateId);
            updateParameters.Add("@src_locate_name", cartonInfo.LocateName);
            updateParameters.Add("@dest_locate_id", 0);
            updateParameters.Add("@dest_locate_name", null);
            updateParameters.Add("@old_qty", cartonInfo.Qty);
            updateParameters.Add("@new_qty", cartonInfo.Qty);
            updateParameters.Add("@trans_qty", cartonInfo.Qty);
            updateParameters.Add("@old_status", cartonInfo.Status);
            updateParameters.Add("@new_status", (int)WmsEnumUtil.StockStatus.SCRAPED);
            updateParameters.Add("@old_qms_status", "N");
            updateParameters.Add("@new_qms_status", "N");
            updateParameters.Add("@unit", cartonInfo.Unit);
            updateParameters.Add("@factory_id", cartonInfo.FactoryId);
            updateParameters.Add("@factory_code", cartonInfo.FactoryCode);
            updateParameters.Add("@src_erp_warehouse", cartonInfo.ErpWarehouse);
            updateParameters.Add("@dest_erp_warehouse", string.Empty);
            updateParameters.Add("@src_warehouse_id", cartonInfo.WarehouseId);
            updateParameters.Add("@src_warehouse_name", cartonInfo.WarehouseName);
            updateParameters.Add("@dest_warehouse_id", 0);
            updateParameters.Add("@dest_warehouse_name", string.Empty);
            updateParameters.Add("@src_zone_id", cartonInfo.ZoneId);
            updateParameters.Add("@src_zone_name", cartonInfo.ZoneName);
            updateParameters.Add("@dest_zone_id", 0);
            updateParameters.Add("@dest_zone_name", string.Empty);
            updateParameters.Add("@enabled", cartonInfo.Enabled);
            updateParameters.Add("@update_userid", loginId);
            updateParameters.Add("@update_time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            updateParameters.Add("@create_userid", loginId);
            updateParameters.Add("@create_time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            updateParameters.Add("@guid", Guid.NewGuid());

            sqlStrings.Add(updateSql.ToString());
            parameterList.Add(updateParameters);

            return this.ExecuteTransaction(sqlStrings, parameterList);

        }

        //获取完成信息提交数据
        public List<WmsMoveDetail_Extend> GetFinishMoveDetailByOrderNo(string orderNo)
        {
            using (IDbConnection dbConn = dapperDbContext.GetDbConnection())
            {
                dbConn.Open();
                StringBuilder SqlStringBuilder = new StringBuilder(1024);
                SqlStringBuilder.Append("SELECT SUM(CONVERT(INT, c.pick_qty)) pick_qty,c.part_no,src_erp_warehouse,dest_erp_warehouse,plan_date,plan_time,a.factory_code,a.order_no,a.ref_order_no  FROM dbo.wms_move_header a (nolock) ");
                SqlStringBuilder.Append("LEFT JOIN dbo.wms_move_detail c (nolock) ON a.order_no=c.order_no ");
                SqlStringBuilder.Append(" WHERE a.order_no = '" + orderNo + "' and a.enabled='Y' group by c.part_no,src_erp_warehouse,dest_erp_warehouse,plan_date,plan_time,a.factory_code,a.order_no,a.ref_order_no");

                List<WmsMoveDetail_Extend> wmsMoves = dbConn.Query<WmsMoveDetail_Extend>(SqlStringBuilder.ToString()).ToList();
                return wmsMoves;
            }
        }

        //获取零件号信息
        public SysPart GetPartNOInfoByPartNo(string partNo)
        {
            using (IDbConnection dbConn = dapperDbContext.GetDbConnection())
            {
                dbConn.Open();
                StringBuilder SqlStringBuilder = new StringBuilder(1024);
                SqlStringBuilder.Append("    SELECT * from sys_part (nolock) where part_no='" + partNo + "' ");
                SysPart sysParts = dbConn.QueryFirstOrDefault<SysPart>(SqlStringBuilder.ToString());
                return sysParts;
            }
        }

        //把结果添加到接口表
        public bool InsertInterfaceByNCScrap(string orderNo)
        {
            using (IDbConnection dbConn = dapperDbContext.GetDbConnection())
            {
                dbConn.Open();
                List<string> sqlStrings = new List<string>();
                List<DynamicParameters> parameterList = new List<DynamicParameters>();

                List<WmsMoveDetail_Extend> wmsMoves = GetFinishMoveDetailByOrderNo(orderNo);
                if (wmsMoves.Count > 0)
                {
                    StringBuilder SqlStringBuilder = new StringBuilder(1024);
                    SqlStringBuilder.Append("INSERT INTO dbo.WMS_MOVR(ZINSTNO,ZEILE,WERKS,LGORT,UMLGO,MATNR,ERFMG ");
                    SqlStringBuilder.Append("           ,ERFME,ACTION,ZPOST,ZTIME, REFORDERNO, SID,RECTIM,SYNFLG");
                    SqlStringBuilder.Append("           ,GUID) ");
                    SqlStringBuilder.Append("     VALUES(@ZINSTNO,@ZEILE,@WERKS,@LGORT,@UMLGO,@MATNR,@ERFMG,@ERFME ");
                    SqlStringBuilder.Append("           ,@ACTION,@ZPOST,@ZTIME, @REFORDERNO, @SID,@RECTIM,@SYNFLG ");
                    SqlStringBuilder.Append("           ,@GUID) ");

                    for (int i = 0; i < wmsMoves.Count; i++)
                    {
                        SysPart sysPart = GetPartNOInfoByPartNo(wmsMoves[i].PartNo);
                        sqlStrings.Add(SqlStringBuilder.ToString());
                        DynamicParameters parameters = new DynamicParameters();
                        parameters.Add("@ZINSTNO", wmsMoves[i].OrderNo);//盘点凭证号
                        parameters.Add("@ZEILE", (i + 1) * 10);//行号
                        parameters.Add("@WERKS", wmsMoves[i].FactoryCode);//工厂
                        parameters.Add("@LGORT", wmsMoves[i].SrcErpWarehouse);//发出库存地点
                        parameters.Add("@UMLGO", wmsMoves[i].DestErpWarehouse);//接收库存地点
                        parameters.Add("@MATNR", wmsMoves[i].PartNo);//物料编码
                        parameters.Add("@ERFMG", wmsMoves[i].PickQty);//转储数量
                        if (sysPart == null)
                        {
                            parameters.Add("@ERFME", "");//计量单位
                        }
                        else
                        {
                            parameters.Add("@ERFME", sysPart.Unit);//计量单位
                        }
                        parameters.Add("@ACTION", "M03"); //M03:NC报废
                        parameters.Add("@ZPOST", DateTime.Now.ToString("yyyyMMdd"));//交易日期
                        parameters.Add("@ZTIME", DateTime.Now.ToString("HHmmss"));//交易时间
						parameters.Add("@REFORDERNO", wmsMoves[i].refOrderNo);//关联单号
						parameters.Add("@SID", Guid.NewGuid().ToString().Replace("-", ""));
                        parameters.Add("@RECTIM", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
						parameters.Add("@SYNFLG", "N");
                        parameters.Add("@GUID", Guid.NewGuid().ToString());


                        parameterList.Add(parameters);
                    }
                }
                IDbTransaction transaction = dbConn.BeginTransaction();
                try
                {
                    bool successCount = true;
                    for (int i = 0; i < sqlStrings.Count; i++)
                    {
                        dbConn.Execute(sqlStrings[i], parameterList[i], transaction);
                    }
                    //提交事务
                    transaction.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    //回滚事务
                    LogHelper.Error("ExecuteTransaction", ex);
                    transaction.Rollback();
                    dbConn.Close();
                    dbConn.Dispose();
                    throw ex;
                }
                finally
                {
                    dbConn.Close();
                    dbConn.Dispose();
                }
            }
        }
    }
}
